package com.fastwire.carriere.controller.impl;

import java.net.MalformedURLException;
import java.util.Comparator;
import java.util.List;

import javax.xml.ws.Holder;

import org.tmforum.mtop.fmw.xsd.hdr.v1.Header;
import org.tmforum.mtop.fmw.xsd.nam.v1.NamingAttributeListType;
import org.tmforum.mtop.fmw.xsd.nam.v1.NamingAttributeType;
import org.tmforum.mtop.nrf.xsd.tpdata.v1.TerminationPointDataListType;
import org.tmforum.mtop.nrf.xsd.tpdata.v1.TerminationPointDataType;
import org.tmforum.mtop.rp.wsdl.fdc.v1_0.FlowDomainControl;
import org.tmforum.mtop.rp.wsdl.fdc.v1_0.FlowDomainControl_Service;
import org.tmforum.mtop.rp.wsdl.fdc.v1_0.ModifyFlowDomainFragmentException;
import org.tmforum.mtop.rp.xsd.fdc.v1.FlowDomainFragmentModifyDataType;
import org.tmforum.mtop.rp.xsd.fdc.v1.ModifyFlowDomainFragmentRequest;
import org.tmforum.mtop.rp.xsd.fdc.v1.ModifyFlowDomainFragmentResponse;
import org.tmforum.mtop.sa.xsd.scai.v1.ModifyServiceActionEnumType;

import com.fastwire.carriere.common.constant.AppConstants;
import com.fastwire.carriere.common.constant.HuaweiInventoryConstants;
import com.fastwire.carriere.common.exception.U2000ProcessException;
import com.fastwire.carriere.common.mapper.NENameMapper;
import com.fastwire.carriere.common.util.EntityUtil;
import com.fastwire.carriere.common.util.StringUtil;
import com.fastwire.carriere.dao.DAOException;
import com.fastwire.carriere.dao.DAOFactory;
import com.fastwire.carriere.dao.FDFRDao;
import com.fastwire.carriere.dao.TrafficConditioningProfileDao;
import com.fastwire.carriere.huawei.mtopsi.ra.HuaweiMTOSIConnection;
import com.fastwire.carriere.inventory.entity.FDFr;
import com.fastwire.carriere.inventory.entity.NetworkElement;
import com.fastwire.carriere.inventory.entity.TrafficConditioningProfile;

// TODO: Auto-generated Javadoc
/**
 * The Class CarPolicyController.
 */
public class CarPolicyControllerImpl {

	/** The tcf dao. */
	private final TrafficConditioningProfileDao tcfDao = DAOFactory
			.getInstance().getTrafficConditioningProfileDao();

	/**
	 * Modify car policy.
	 * 
	 * @param carPolicy
	 *            the car policy
	 * @param fdfr
	 *            the fdfr
	 * @throws U2000ProcessException
	 *             the u2000 process exception
	 * @throws MalformedURLException
	 *             the malformed url exception
	 */
	private void modifyCarPolicy(String carPolicy, FDFr fdfr)
			throws U2000ProcessException, MalformedURLException {
		ModifyFlowDomainFragmentRequest request = new ModifyFlowDomainFragmentRequest();
		Holder<Header> headerHolder = HuaweiMTOSIConnection
				.getSingleResponseHeader();

		request.setFdfrRef(EntityUtil.convertNameToNamingAttributeType(fdfr
				.getName()));
		request.setAction(ModifyServiceActionEnumType.MODIFY);

		request.setModifyData(new FlowDomainFragmentModifyDataType());
		FlowDomainFragmentModifyDataType flowDomainFragmentModifyDataType = request
				.getModifyData();
		flowDomainFragmentModifyDataType
				.setAEndTpRefList(new NamingAttributeListType());
		NamingAttributeListType namingAttributeListType = flowDomainFragmentModifyDataType
				.getAEndTpRefList();
		List<NamingAttributeType> namingAttributeTypes = namingAttributeListType
				.getName();
		namingAttributeTypes.add(EntityUtil
				.convertNameToNamingAttributeType(fdfr.getAendTp().getName()));
		request.setTpDataListToModify(new TerminationPointDataListType());

		TerminationPointDataListType tpDataListType = request
				.getTpDataListToModify();
		List<TerminationPointDataType> tPointDataTypes = tpDataListType
				.getTpData();

		TerminationPointDataType tpDataType = new TerminationPointDataType();
		tpDataType.setTpRef(EntityUtil.convertNameToNamingAttributeType(fdfr
				.getAendTp().getName()));
		tpDataType.setIngressTmdRef(EntityUtil
				.convertNameToNamingAttributeType(carPolicy));
		tPointDataTypes.add(tpDataType);

		FlowDomainControl_Service service = new FlowDomainControl_Service(
				HuaweiMTOSIConnection
						.getWebServiceURL(AppConstants.FDFR_CONTROL));
		FlowDomainControl port = service.getFlowDomainControl();
		Holder<ModifyFlowDomainFragmentResponse> responseHolder = new Holder<ModifyFlowDomainFragmentResponse>();

		try {
			port.modifyFlowDomainFragment(headerHolder, request, responseHolder);
		} catch (ModifyFlowDomainFragmentException e) {
			throw new U2000ProcessException(e.getMessage());
		}

	}

	/**
	 * Gets the matching traffic profile.
	 * 
	 * @param fdfr
	 *            the fdfr
	 * @param newBandwidth
	 *            the new bandwidth
	 * @return the matching traffic profile
	 * @throws DAOException
	 *             the dAO exception
	 */
	public TrafficConditioningProfile getMatchingTrafficProfile(FDFr fdfr,
			int newBandwidth) throws DAOException {

		NetworkElement networkElement = NENameMapper.getNEbyU2kName(fdfr
				.getName());
		String type = HuaweiInventoryConstants.NETYPE_TCP_MAP
				.get(networkElement.getNeType());
		if (!StringUtil.isEmptyString(type)) {
			List<TrafficConditioningProfile> tcfList = tcfDao
					.getTrafficConditioningProfilesbyDevTypeAndBandwidth(type,
							newBandwidth);

			if (tcfList != null && !tcfList.isEmpty()) {
				java.util.Collections.sort(tcfList, new TCFComparator());

				return tcfList.get(0);
			}
		}
		return null;

	}

	/**
	 * Modify car policy.
	 * 
	 * @param fdfrName
	 *            the fdfr name
	 * @param newBandwidth
	 *            the new bandwidth
	 * @throws DAOException
	 *             the dAO exception
	 * @throws U2000ProcessException
	 *             the u2000 process exception
	 * @throws MalformedURLException
	 *             the malformed url exception
	 */
	public void modifyCarPolicy(String fdfrName, int newBandwidth)
			throws DAOException, U2000ProcessException, MalformedURLException {

		FDFRDao fdfrDao = DAOFactory.getInstance().getFdfrDao();
		List<FDFr> fdfrList = fdfrDao.findFdFrbyServiceId(fdfrName);

		for (FDFr fdfr : fdfrList) {
			TrafficConditioningProfile tcf = getMatchingTrafficProfile(fdfr,
					newBandwidth);

			if (tcf != null) {
				modifyCarPolicy(tcf.getName(), fdfr);
				fdfr.getAendTp().setIngressTmdRef(tcf.getName());
				fdfrDao.saveOrUpdateFDFR(fdfr);

			}
			//fdfr.getAendTp().setIngressTmdRef(tcf.getName());

		}
		//fdfrDao.saveOrUpdateAll(fdfrList);
	}

	/**
	 * The Class TCFComparator.
	 */
	public static class TCFComparator implements
			Comparator<TrafficConditioningProfile> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		@Override
		public int compare(TrafficConditioningProfile first,
				TrafficConditioningProfile second) {

			int first_bandwidth = first.getBandwidth();
			int second_bandwidth = second.getBandwidth();

			return Integer.valueOf(first_bandwidth).compareTo(second_bandwidth);

		}

	}
}
